require 'rbof'

module OF
  def self.has_alias(name, arity)
    result = name.dup
    result.gsub!(/([^A-Z])([A-Z])/, '\1_\2')
    result.downcase!
    result.gsub!(/^get_/, '')
    result.gsub!(/^(b_|is_)(.*)/, '\2?')
    if arity == 1
      result.gsub!(/^set_(.*)/, '\1=')
    else
      result.gsub!(/^set_/, '')
    end
    yield(result) if name != result
  end
  private_class_method :has_alias
  
  def self.event_handler?(klass, name)
    klass == SimpleApp && !["mouseX", "mouseY"].include?(name)
  end
  private_class_method :event_handler?
  
  def self.rename_instance_methods!
    classes = constants.map {|name| const_get(name)} \
              .delete_if {|klass| not klass.is_a? Class}
    classes.each do |klass|
      klass.instance_methods(false).each do |name|
        f = klass.instance_method(name)
        has_alias(name, f.arity) do |newname|
          is_handler = event_handler?(klass, name)
          klass.class_eval do
            alias_method(newname, name)
            if is_handler
              define_method(name) do |*args|
                __send__(newname, *args)
              end
              private(name)
            else
              undef_method(name)
            end
          end
        end
      end
    end
  end
  private_class_method :rename_instance_methods!
  
  def self.rename_module_functions!
    methods(false).each do |name|
      f = method(name)
      has_alias(name, f.arity) do |newname|
        alias_method(newname, name)
        module_function(newname)
        private_class_method(name)
        undef_method(name)
      end
    end
  end
  private_class_method :rename_module_functions!
  
  rename_instance_methods!
  rename_module_functions!
end